import { useVueFlow } from '@vue-flow/core'
import { ref, watch, type Ref } from 'vue'
import type { Node, XYPosition } from '@vue-flow/core'

let id = 0

/**
 * 生成唯一ID
 */
function getId(): string {
    return `dndnode_${id++}`
}

// 定义节点类型
type NodeType = 'input' | 'default' | 'output'

// 定义状态类型
interface DragState {
    draggedType: Ref<NodeType | null>
    isDragOver: Ref<boolean>
    isDragging: Ref<boolean>
}

// 定义 VueFlow 实例接口
interface VueFlowInstance {
    addNodes: (nodes: Node | Node[]) => void
    screenToFlowCoordinate: (position: { x: number; y: number }) => XYPosition
    onNodesInitialized: (callback: () => void) => { off: () => void }
    updateNode: (nodeId: string, updater: (node: Node) => Partial<Node>) => void
}

// 定义返回类型
interface UseDragAndDropReturn {
    draggedType: Ref<NodeType | null>
    isDragOver: Ref<boolean>
    isDragging: Ref<boolean>
    onDragStart: (event: DragEvent, type: NodeType, processData?: any) => void
    onDragLeave: (event: DragEvent) => void
    onDragOver: (event: DragEvent) => void
    onDrop: (event: DragEvent) => void
}

/**
 * 在真实场景中，你应该避免在全局作用域创建 refs，因为它们可能不会被正确清理
 */
const state: DragState = {
    /**
     * 被拖拽节点的类型
     */
    draggedType: ref<NodeType | null>(null),
    isDragOver: ref<boolean>(false),
    isDragging: ref<boolean>(false),
}

export default function useDragAndDrop(vueFlowInstance?: VueFlowInstance): UseDragAndDropReturn {
    const { draggedType, isDragOver, isDragging } = state

    // 如果传入了 VueFlow 实例，使用它；否则使用默认的
    const flowInstance = vueFlowInstance || useVueFlow()
    const { addNodes, screenToFlowCoordinate, onNodesInitialized, updateNode } = flowInstance

    watch(isDragging, (dragging: boolean) => {
        document.body.style.userSelect = dragging ? 'none' : ''
    })

    function onDragStart(event: DragEvent, type: NodeType, processData?: any): void {
        if (event.dataTransfer) {
            event.dataTransfer.setData('application/vueflow', type)
            event.dataTransfer.effectAllowed = 'move'

            // 如果有工序数据，存储工序信息
            if (processData) {
                event.dataTransfer.setData('application/process', JSON.stringify(processData))
                // 构建完整的标签格式：(工序编码)工序名称
                const label = `(${processData.processCode})${processData.processName}`
                event.dataTransfer.setData('label', label)
            } else {
                // 获取拖拽元素的文本内容作为标签
                const target = event.target as HTMLElement
                const label = target.textContent || target.innerText || ''
                event.dataTransfer.setData('label', label)
            }
        }

        draggedType.value = type
        isDragging.value = true
    }

    /**
     * 处理拖拽悬停事件
     */
    function onDragOver(event: DragEvent): void {
        event.preventDefault()

        if (draggedType.value) {
            isDragOver.value = true

            if (event.dataTransfer) {
                event.dataTransfer.dropEffect = 'move'
            }
        }
    }

    function onDragLeave(event: DragEvent): void {
        // 只有当离开的是容器本身时才设置为false
        if (!event.currentTarget || !event.relatedTarget ||
            !(event.currentTarget as Element).contains(event.relatedTarget as Element)) {
            isDragOver.value = false
        }
    }

    function onDragEnd(): void {
        isDragging.value = false
        isDragOver.value = false
        draggedType.value = null
    }

    /**
     * 处理放置事件
     */
    function onDrop(event: DragEvent): void {
        event.preventDefault()
        console.log('onDrop 事件触发')

        // 检查是否有拖拽的节点类型
        if (!draggedType.value) {
            console.log('没有拖拽类型，退出')
            return
        }

        console.log('拖拽类型:', draggedType.value)

        const position = screenToFlowCoordinate({
            x: event.clientX,
            y: event.clientY,
        })

        console.log('计算位置:', position)

        const nodeId = getId()

        // 获取标签和工序数据
        const label = event.dataTransfer?.getData('label') || ''
        const processDataStr = event.dataTransfer?.getData('application/process')
        let processData = null

        console.log('标签:', label)
        console.log('工序数据字符串:', processDataStr)

        if (processDataStr) {
            try {
                processData = JSON.parse(processDataStr)
                console.log('解析的工序数据:', processData)
            } catch (e) {
                console.warn('解析工序数据失败:', e)
            }
        }

        // 创建节点数据
        const nodeData: any = {
            label: label || '未命名节点'
        }

        // 如果有工序数据，添加到节点数据中
        if (processData) {
            nodeData.processId = processData.id
            nodeData.processCode = processData.processCode
            nodeData.processName = processData.processName
            nodeData.status = processData.status
            nodeData.workOrderId = processData.workOrderId
        }

        const newNode: Node = {
            id: nodeId,
            type: draggedType.value as NodeType,
            position,
            data: nodeData
        }

        console.log('创建的新节点:', newNode)

        // 直接添加节点
        addNodes(newNode)
        console.log('节点已添加到 VueFlow')

        // 重置拖拽状态
        onDragEnd()
    }

    return {
        draggedType,
        isDragOver,
        isDragging,
        onDragStart,
        onDragLeave,
        onDragOver,
        onDrop,
    }
}